home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / math.s < prev    next >
Text File  |  2000-05-22  |  11KB  |  419 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. //
  21. // math.s
  22. // x86 assembly-language math routines.
  23.  
  24. #define GLQUAKE    1    // don't include unneeded defs
  25. #include "asm_i386.h"
  26. #include "quakeasm.h"
  27.  
  28.  
  29. #if    id386
  30.  
  31.     .data
  32.  
  33.     .align    4
  34. Ljmptab:    .long    Lcase0, Lcase1, Lcase2, Lcase3
  35.             .long    Lcase4, Lcase5, Lcase6, Lcase7
  36.  
  37.     .text
  38.  
  39. // TODO: rounding needed?
  40. // stack parameter offset
  41. #define    val    4
  42.  
  43. .globl C(Invert24To16)
  44. C(Invert24To16):
  45.  
  46.     movl    val(%esp),%ecx
  47.     movl    $0x100,%edx        // 0x10000000000 as dividend
  48.     cmpl    %edx,%ecx
  49.     jle        LOutOfRange
  50.  
  51.     subl    %eax,%eax
  52.     divl    %ecx
  53.  
  54.     ret
  55.  
  56. LOutOfRange:
  57.     movl    $0xFFFFFFFF,%eax
  58.     ret
  59.  
  60. #define    in    4
  61. #define out    8
  62.  
  63.     .align 2
  64. .globl C(TransformVector)
  65. C(TransformVector):
  66.     movl    in(%esp),%eax
  67.     movl    out(%esp),%edx
  68.  
  69.     flds    (%eax)        // in[0]
  70.     fmuls    C(vright)        // in[0]*vright[0]
  71.     flds    (%eax)        // in[0] | in[0]*vright[0]
  72.     fmuls    C(vup)        // in[0]*vup[0] | in[0]*vright[0]
  73.     flds    (%eax)        // in[0] | in[0]*vup[0] | in[0]*vright[0]
  74.     fmuls    C(vpn)        // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
  75.  
  76.     flds    4(%eax)        // in[1] | ...
  77.     fmuls    C(vright)+4    // in[1]*vright[1] | ...
  78.     flds    4(%eax)        // in[1] | in[1]*vright[1] | ...
  79.     fmuls    C(vup)+4        // in[1]*vup[1] | in[1]*vright[1] | ...
  80.     flds    4(%eax)        // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
  81.     fmuls    C(vpn)+4        // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
  82.     fxch    %st(2)        // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
  83.  
  84.     faddp    %st(0),%st(5)    // in[1]*vup[1] | in[1]*vpn[1] | ...
  85.     faddp    %st(0),%st(3)    // in[1]*vpn[1] | ...
  86.     faddp    %st(0),%st(1)    // vpn_accum | vup_accum | vright_accum
  87.  
  88.     flds    8(%eax)        // in[2] | ...
  89.     fmuls    C(vright)+8    // in[2]*vright[2] | ...
  90.     flds    8(%eax)        // in[2] | in[2]*vright[2] | ...
  91.     fmuls    C(vup)+8        // in[2]*vup[2] | in[2]*vright[2] | ...
  92.     flds    8(%eax)        // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
  93.     fmuls    C(vpn)+8        // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
  94.     fxch    %st(2)        // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
  95.  
  96.     faddp    %st(0),%st(5)    // in[2]*vup[2] | in[2]*vpn[2] | ...
  97.     faddp    %st(0),%st(3)    // in[2]*vpn[2] | ...
  98.     faddp    %st(0),%st(1)    // vpn_accum | vup_accum | vright_accum
  99.  
  100.     fstps    8(%edx)        // out[2]
  101.     fstps    4(%edx)        // out[1]
  102.     fstps    (%edx)        // out[0]
  103.  
  104.     ret
  105.  
  106.  
  107. #define EMINS    4+4
  108. #define EMAXS    4+8
  109. #define P        4+12
  110.  
  111.     .align 2
  112. .globl C(BoxOnPlaneSide)
  113. C(BoxOnPlaneSide):
  114.     pushl    %ebx
  115.  
  116.     movl    P(%esp),%edx
  117.     movl    EMINS(%esp),%ecx
  118.     xorl    %eax,%eax
  119.     movl    EMAXS(%esp),%ebx
  120.     movb    pl_signbits(%edx),%al
  121.     cmpb    $8,%al
  122.     jge        Lerror
  123.     flds    pl_normal(%edx)        // p->normal[0]
  124.     fld        %st(0)                // p->normal[0] | p->normal[0]
  125.     jmp        Ljmptab(,%eax,4)
  126.  
  127.  
  128. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  129. //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  130. Lcase0:
  131.     fmuls    (%ebx)                // p->normal[0]*emaxs[0] | p->normal[0]
  132.     flds    pl_normal+4(%edx)    // p->normal[1] | p->normal[0]*emaxs[0] |
  133.                                 //  p->normal[0]
  134.     fxch    %st(2)                // p->normal[0] | p->normal[0]*emaxs[0] |
  135.                                 //  p->normal[1]
  136.     fmuls    (%ecx)                // p->normal[0]*emins[0] |
  137.                                 //  p->normal[0]*emaxs[0] | p->normal[1]
  138.     fxch    %st(2)                // p->normal[1] | p->normal[0]*emaxs[0] |
  139.                                 //  p->normal[0]*emins[0]
  140.     fld        %st(0)                // p->normal[1] | p->normal[1] |
  141.                                 //  p->normal[0]*emaxs[0] |
  142.                                 //  p->normal[0]*emins[0]
  143.     fmuls    4(%ebx)                // p->normal[1]*emaxs[1] | p->normal[1] |
  144.                                 //  p->normal[0]*emaxs[0] |
  145.                                 //  p->normal[0]*emins[0]
  146.     flds    pl_normal+8(%edx)    // p->normal[2] | p->normal[1]*emaxs[1] |
  147.                                 //  p->normal[1] | p->normal[0]*emaxs[0] |
  148.                                 //  p->normal[0]*emins[0]
  149.     fxch    %st(2)                // p->normal[1] | p->normal[1]*emaxs[1] |
  150.                                 //  p->normal[2] | p->normal[0]*emaxs[0] |
  151.                                 //  p->normal[0]*emins[0]
  152.     fmuls    4(%ecx)                // p->normal[1]*emins[1] |
  153.                                 //  p->normal[1]*emaxs[1] |
  154.                                 //  p->normal[2] | p->normal[0]*emaxs[0] |
  155.                                 //  p->normal[0]*emins[0]
  156.     fxch    %st(2)                // p->normal[2] | p->normal[1]*emaxs[1] |
  157.                                 //  p->normal[1]*emins[1] |
  158.                                 //  p->normal[0]*emaxs[0] |
  159.                                 //  p->normal[0]*emins[0]
  160.     fld        %st(0)                // p->normal[2] | p->normal[2] |
  161.                                 //  p->normal[1]*emaxs[1] |
  162.                                 //  p->normal[1]*emins[1] |
  163.                                 //  p->normal[0]*emaxs[0] |
  164.                                 //  p->normal[0]*emins[0]
  165.     fmuls    8(%ebx)                // p->normal[2]*emaxs[2] |
  166.                                 //  p->normal[2] |
  167.                                 //  p->normal[1]*emaxs[1] |
  168.                                 //  p->normal[1]*emins[1] |
  169.                                 //  p->normal[0]*emaxs[0] |
  170.                                 //  p->normal[0]*emins[0]
  171.     fxch    %st(5)                // p->normal[0]*emins[0] |
  172.                                 //  p->normal[2] |
  173.                                 //  p->normal[1]*emaxs[1] |
  174.                                 //  p->normal[1]*emins[1] |
  175.                                 //  p->normal[0]*emaxs[0] |
  176.                                 //  p->normal[2]*emaxs[2]
  177.     faddp    %st(0),%st(3)        //p->normal[2] |
  178.                                 // p->normal[1]*emaxs[1] |
  179.                                 // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  180.                                 // p->normal[0]*emaxs[0] |
  181.                                 // p->normal[2]*emaxs[2]
  182.     fmuls    8(%ecx)                //p->normal[2]*emins[2] |
  183.                                 // p->normal[1]*emaxs[1] |
  184.                                 // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  185.                                 // p->normal[0]*emaxs[0] |
  186.                                 // p->normal[2]*emaxs[2]
  187.     fxch    %st(1)                //p->normal[1]*emaxs[1] |
  188.                                 // p->normal[2]*emins[2] |
  189.                                 // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  190.                                 // p->normal[0]*emaxs[0] |
  191.                                 // p->normal[2]*emaxs[2]
  192.     faddp    %st(0),%st(3)        //p->normal[2]*emins[2] |
  193.                                 // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  194.                                 // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
  195.                                 // p->normal[2]*emaxs[2]
  196.     fxch    %st(3)                //p->normal[2]*emaxs[2] +
  197.                                 // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  198.                                 // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
  199.                                 // p->normal[2]*emins[2]
  200.     faddp    %st(0),%st(2)        //p->normal[1]*emins[1]+p->normal[0]*emins[0]|
  201.                                 // dist1 | p->normal[2]*emins[2]
  202.  
  203.     jmp        LSetSides
  204.  
  205. //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  206. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  207. Lcase1:
  208.     fmuls    (%ecx)                // emins[0]
  209.     flds    pl_normal+4(%edx)
  210.     fxch    %st(2)
  211.     fmuls    (%ebx)                // emaxs[0]
  212.     fxch    %st(2)
  213.     fld        %st(0)
  214.     fmuls    4(%ebx)                // emaxs[1]
  215.     flds    pl_normal+8(%edx)
  216.     fxch    %st(2)
  217.     fmuls    4(%ecx)                // emins[1]
  218.     fxch    %st(2)
  219.     fld        %st(0)
  220.     fmuls    8(%ebx)                // emaxs[2]
  221.     fxch    %st(5)
  222.     faddp    %st(0),%st(3)
  223.     fmuls    8(%ecx)                // emins[2]
  224.     fxch    %st(1)
  225.     faddp    %st(0),%st(3)
  226.     fxch    %st(3)
  227.     faddp    %st(0),%st(2)
  228.  
  229.     jmp        LSetSides
  230.  
  231. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  232. //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  233. Lcase2:
  234.     fmuls    (%ebx)                // emaxs[0]
  235.     flds    pl_normal+4(%edx)
  236.     fxch    %st(2)
  237.     fmuls    (%ecx)                // emins[0]
  238.     fxch    %st(2)
  239.     fld        %st(0)
  240.     fmuls    4(%ecx)                // emins[1]
  241.     flds    pl_normal+8(%edx)
  242.     fxch    %st(2)
  243.     fmuls    4(%ebx)                // emaxs[1]
  244.     fxch    %st(2)
  245.     fld        %st(0)
  246.     fmuls    8(%ebx)                // emaxs[2]
  247.     fxch    %st(5)
  248.     faddp    %st(0),%st(3)
  249.     fmuls    8(%ecx)                // emins[2]
  250.     fxch    %st(1)
  251.     faddp    %st(0),%st(3)
  252.     fxch    %st(3)
  253.     faddp    %st(0),%st(2)
  254.  
  255.     jmp        LSetSides
  256.  
  257. //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  258. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  259. Lcase3:
  260.     fmuls    (%ecx)                // emins[0]
  261.     flds    pl_normal+4(%edx)
  262.     fxch    %st(2)
  263.     fmuls    (%ebx)                // emaxs[0]
  264.     fxch    %st(2)
  265.     fld        %st(0)
  266.     fmuls    4(%ecx)                // emins[1]
  267.     flds    pl_normal+8(%edx)
  268.     fxch    %st(2)
  269.     fmuls    4(%ebx)                // emaxs[1]
  270.     fxch    %st(2)
  271.     fld        %st(0)
  272.     fmuls    8(%ebx)                // emaxs[2]
  273.     fxch    %st(5)
  274.     faddp    %st(0),%st(3)
  275.     fmuls    8(%ecx)                // emins[2]
  276.     fxch    %st(1)
  277.     faddp    %st(0),%st(3)
  278.     fxch    %st(3)
  279.     faddp    %st(0),%st(2)
  280.  
  281.     jmp        LSetSides
  282.  
  283. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  284. //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  285. Lcase4:
  286.     fmuls    (%ebx)                // emaxs[0]
  287.     flds    pl_normal+4(%edx)
  288.     fxch    %st(2)
  289.     fmuls    (%ecx)                // emins[0]
  290.     fxch    %st(2)
  291.     fld        %st(0)
  292.     fmuls    4(%ebx)                // emaxs[1]
  293.     flds    pl_normal+8(%edx)
  294.     fxch    %st(2)
  295.     fmuls    4(%ecx)                // emins[1]
  296.     fxch    %st(2)
  297.     fld        %st(0)
  298.     fmuls    8(%ecx)                // emins[2]
  299.     fxch    %st(5)
  300.     faddp    %st(0),%st(3)
  301.     fmuls    8(%ebx)                // emaxs[2]
  302.     fxch    %st(1)
  303.     faddp    %st(0),%st(3)
  304.     fxch    %st(3)
  305.     faddp    %st(0),%st(2)
  306.  
  307.     jmp        LSetSides
  308.  
  309. //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  310. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  311. Lcase5:
  312.     fmuls    (%ecx)                // emins[0]
  313.     flds    pl_normal+4(%edx)
  314.     fxch    %st(2)
  315.     fmuls    (%ebx)                // emaxs[0]
  316.     fxch    %st(2)
  317.     fld        %st(0)
  318.     fmuls    4(%ebx)                // emaxs[1]
  319.     flds    pl_normal+8(%edx)
  320.     fxch    %st(2)
  321.     fmuls    4(%ecx)                // emins[1]
  322.     fxch    %st(2)
  323.     fld        %st(0)
  324.     fmuls    8(%ecx)                // emins[2]
  325.     fxch    %st(5)
  326.     faddp    %st(0),%st(3)
  327.     fmuls    8(%ebx)                // emaxs[2]
  328.     fxch    %st(1)
  329.     faddp    %st(0),%st(3)
  330.     fxch    %st(3)
  331.     faddp    %st(0),%st(2)
  332.  
  333.     jmp        LSetSides
  334.  
  335. //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  336. //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  337. Lcase6:
  338.     fmuls    (%ebx)                // emaxs[0]
  339.     flds    pl_normal+4(%edx)
  340.     fxch    %st(2)
  341.     fmuls    (%ecx)                // emins[0]
  342.     fxch    %st(2)
  343.     fld        %st(0)
  344.     fmuls    4(%ecx)                // emins[1]
  345.     flds    pl_normal+8(%edx)
  346.     fxch    %st(2)
  347.     fmuls    4(%ebx)                // emaxs[1]
  348.     fxch    %st(2)
  349.     fld        %st(0)
  350.     fmuls    8(%ecx)                // emins[2]
  351.     fxch    %st(5)
  352.     faddp    %st(0),%st(3)
  353.     fmuls    8(%ebx)                // emaxs[2]
  354.     fxch    %st(1)
  355.     faddp    %st(0),%st(3)
  356.     fxch    %st(3)
  357.     faddp    %st(0),%st(2)
  358.  
  359.     jmp        LSetSides
  360.  
  361. //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  362. //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  363. Lcase7:
  364.     fmuls    (%ecx)                // emins[0]
  365.     flds    pl_normal+4(%edx)
  366.     fxch    %st(2)
  367.     fmuls    (%ebx)                // emaxs[0]
  368.     fxch    %st(2)
  369.     fld        %st(0)
  370.     fmuls    4(%ecx)                // emins[1]
  371.     flds    pl_normal+8(%edx)
  372.     fxch    %st(2)
  373.     fmuls    4(%ebx)                // emaxs[1]
  374.     fxch    %st(2)
  375.     fld        %st(0)
  376.     fmuls    8(%ecx)                // emins[2]
  377.     fxch    %st(5)
  378.     faddp    %st(0),%st(3)
  379.     fmuls    8(%ebx)                // emaxs[2]
  380.     fxch    %st(1)
  381.     faddp    %st(0),%st(3)
  382.     fxch    %st(3)
  383.     faddp    %st(0),%st(2)
  384.  
  385. LSetSides:
  386.  
  387. //    sides = 0;
  388. //    if (dist1 >= p->dist)
  389. //        sides = 1;
  390. //    if (dist2 < p->dist)
  391. //        sides |= 2;
  392.  
  393.     faddp    %st(0),%st(2)        // dist1 | dist2
  394.     fcomps    pl_dist(%edx)
  395.     xorl    %ecx,%ecx
  396.     fnstsw    %ax
  397.     fcomps    pl_dist(%edx)
  398.     andb    $1,%ah
  399.     xorb    $1,%ah
  400.     addb    %ah,%cl
  401.  
  402.     fnstsw    %ax
  403.     andb    $1,%ah
  404.     addb    %ah,%ah
  405.     addb    %ah,%cl
  406.  
  407. //    return sides;
  408.  
  409.     popl    %ebx
  410.     movl    %ecx,%eax    // return status
  411.  
  412.     ret
  413.  
  414.  
  415. Lerror:
  416.     call    C(BOPS_Error)
  417.  
  418. #endif    // id386
  419.